/*
 * <h3>Title:wheel-spring-boot-web-starter系统</h3>
 * <p>Copyright (c) 2019. All rights reserved.</p>
 * @author wnfbx@163.com
 */
package com.wheel.autoconfigure.web.mvc.rest;

import com.wheel.core.exception.*;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.Map;
import java.util.Set;

/**
 * <dt>Description:BaseRestTemplate</dt>
 * <dd>springresttemplate 基础调用对象</dd>
 *
 * @author wnfbx@163.com
 * @version 1.0 <i>2019年6月6日 下午1:35:52</i>
 * @since jdk1.7+
 */
public class BaseRestTemplate {

    /**
     * restTemplate:
     */
    private RestTemplate restTemplate;

    /**
     * <dt>Description:BaseRestTemplate</dt>
     * <dd>构造注入</dd>
     * <dd>author: wangnaifei@163.com</dd>
     * <dd>version:1.0 <i>2019/12/11 18:05</i></dd>
     *
     * @param restTemplate 传入spring初始化后的对象
     * @since jdk1.7+
     */
    public BaseRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    /**
     * <dt>Description:</dt>
     * <dd>获取</dd>
     * <dd>author wnfbx@163.com</dd>
     * <dd>version 1.0 <i>2019年6月6日 下午2:39:11</i></dd>
     *
     * @return {@link RestTemplate}
     */
    public RestTemplate getRestTemplate() {
        return restTemplate;
    }

    // GET
    public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
            throws RemoteRestGetException {
        try {
            return restTemplate.getForObject(url, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestGetException(e);
        }
    }

    public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
            throws RemoteRestGetException {
        try {
            return restTemplate.getForObject(url, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestGetException(e);
        }
    }

    public <T> T getForObject(URI url, Class<T> responseType) throws RemoteRestGetException {
        try {
            return restTemplate.getForObject(url, responseType);
        } catch (RestClientException e) {
            throw new RemoteRestGetException(e);
        }
    }

    public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
            throws RemoteRestGetException {
        try {
            return restTemplate.getForEntity(url, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestGetException(e);
        }
    }

    public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
            throws RemoteRestGetException {
        try {
            return restTemplate.getForEntity(url, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestGetException(e);
        }
    }

    public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RemoteRestGetException {
        try {
            return restTemplate.getForEntity(url, responseType);
        } catch (RestClientException e) {
            throw new RemoteRestGetException(e);
        }
    }

    // HEAD
    public HttpHeaders headForHeaders(String url, Object... uriVariables) throws RemoteRestHeadException {
        try {
            return restTemplate.headForHeaders(url, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestHeadException(e);
        }
    }

    public HttpHeaders headForHeaders(String url, Map<String, ?> uriVariables) throws RemoteRestHeadException {
        try {
            return restTemplate.headForHeaders(url, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestHeadException(e);
        }
    }

    public HttpHeaders headForHeaders(URI url) throws RemoteRestHeadException {
        try {
            return restTemplate.headForHeaders(url);
        } catch (RestClientException e) {
            throw new RemoteRestHeadException(e);
        }
    }

    // POST
    public URI postForLocation(String url, Object request, Object... uriVariables) throws RemoteRestPostException {
        try {
            return restTemplate.postForLocation(url, request, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPostException(e);
        }
    }

    public URI postForLocation(String url, Object request, Map<String, ?> uriVariables)
            throws RemoteRestPostException {
        try {
            return restTemplate.postForLocation(url, request, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPostException(e);
        }
    }

    public URI postForLocation(URI url, Object request) throws RemoteRestPostException {
        try {
            return restTemplate.postForLocation(url, request);
        } catch (RestClientException e) {
            throw new RemoteRestPostException(e);
        }
    }

    public <T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
            throws RemoteRestPostException {
        try {
            return restTemplate.postForObject(url, request, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPostException(e);
        }
    }

    public <T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
            throws RemoteRestPostException {
        try {
            return restTemplate.postForObject(url, request, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPostException(e);
        }
    }

    public <T> T postForObject(URI url, Object request, Class<T> responseType) throws RemoteRestPostException {
        try {
            return restTemplate.postForObject(url, request, responseType);
        } catch (RestClientException e) {
            throw new RemoteRestPostException(e);
        }
    }

    public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType,
                                               Object... uriVariables) throws RemoteRestPostException {
        try {
            return restTemplate.postForEntity(url, request, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPostException(e);
        }
    }

    public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType,
                                               Map<String, ?> uriVariables) throws RemoteRestPostException {
        try {
            return restTemplate.postForEntity(url, request, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPostException(e);
        }
    }

    public <T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType)
            throws RemoteRestPostException {
        try {
            return restTemplate.postForEntity(url, request, responseType);
        } catch (RestClientException e) {
            throw new RemoteRestPostException(e);
        }
    }

    // PUT
    public void put(String url, Object request, Object... uriVariables) throws RemoteRestPutException {
        try {
            restTemplate.put(url, request, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPutException(e);
        }
    }

    public void put(String url, Object request, Map<String, ?> uriVariables) throws RemoteRestPutException {
        try {
            restTemplate.put(url, request, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPutException(e);
        }
    }

    public void put(URI url, Object request) throws RemoteRestPutException {
        try {
            restTemplate.put(url, request);
        } catch (RestClientException e) {
            throw new RemoteRestPutException(e);
        }
    }

    // PATCH
    public <T> T patchForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
            throws RemoteRestPatchException {
        try {
            return restTemplate.patchForObject(url, request, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPatchException(e);
        }
    }

    public <T> T patchForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
            throws RemoteRestPatchException {
        try {
            return restTemplate.patchForObject(url, request, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestPatchException(e);
        }
    }

    public <T> T patchForObject(URI url, Object request, Class<T> responseType) throws RemoteRestPatchException {
        try {
            return restTemplate.patchForObject(url, request, responseType);
        } catch (RestClientException e) {
            throw new RemoteRestPatchException(e);
        }
    }

    // DELETE
    public void delete(String url, Object... uriVariables) throws RemoteRestDeleteException {
        try {
            restTemplate.delete(url, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestDeleteException(e);
        }
    }

    public void delete(String url, Map<String, ?> uriVariables) throws RemoteRestDeleteException {
        try {
            restTemplate.delete(url, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestDeleteException(e);
        }
    }

    public void delete(URI url) throws RemoteRestDeleteException {
        try {
            restTemplate.delete(url);
        } catch (RestClientException e) {
            throw new RemoteRestDeleteException(e);
        }
    }

    // OPTIONS
    public Set<HttpMethod> optionsForAllow(String url, Object... uriVariables) throws RemoteRestOptionsException {
        try {
            return restTemplate.optionsForAllow(url, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestOptionsException(e);
        }
    }

    public Set<HttpMethod> optionsForAllow(String url, Map<String, ?> uriVariables) throws RemoteRestOptionsException {
        try {
            return restTemplate.optionsForAllow(url, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestOptionsException(e);
        }
    }

    public Set<HttpMethod> optionsForAllow(URI url) throws RemoteRestOptionsException {
        try {
            return restTemplate.optionsForAllow(url);
        } catch (RestClientException e) {
            throw new RemoteRestOptionsException(e);
        }
    }

    // exchange
    public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
                                          Class<T> responseType, Object... uriVariables) throws RemoteRestExchangeException {
        try {
            return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestExchangeException(e);
        }
    }

    public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
                                          Class<T> responseType, Map<String, ?> uriVariables) throws RemoteRestExchangeException {
        try {
            return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestExchangeException(e);
        }
    }

    public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
                                          Class<T> responseType) throws RemoteRestExchangeException {
        try {
            return restTemplate.exchange(url, method, requestEntity, responseType);
        } catch (RestClientException e) {
            throw new RemoteRestExchangeException(e);
        }
    }

    public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
                                          ParameterizedTypeReference<T> responseType, Object... uriVariables) throws RemoteRestExchangeException {
        try {
            return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestExchangeException(e);
        }
    }

    public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
                                          ParameterizedTypeReference<T> responseType, Map<String, ?> uriVariables)
            throws RemoteRestExchangeException {
        try {
            return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
        } catch (RestClientException e) {
            throw new RemoteRestExchangeException(e);
        }
    }

    public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
                                          ParameterizedTypeReference<T> responseType) throws RemoteRestExchangeException {
        try {
            return restTemplate.exchange(url, method, requestEntity, responseType);
        } catch (RestClientException e) {
            throw new RemoteRestExchangeException(e);
        }
    }

    public <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, Class<T> responseType)
            throws RemoteRestExchangeException {
        try {
            return restTemplate.exchange(requestEntity, responseType);
        } catch (RestClientException e) {
            throw new RemoteRestExchangeException(e);
        }
    }

    public <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)
            throws RemoteRestExchangeException {
        try {
            return restTemplate.exchange(requestEntity, responseType);
        } catch (RestClientException e) {
            throw new RemoteRestExchangeException(e);
        }
    }
}
